package cn.ijero.pictureselector.loader.db;

import static android.provider.MediaStore.MediaColumns.DATE_ADDED;

import android.annotation.SuppressLint;
import android.content.Context;
import android.database.Cursor;

import androidx.annotation.NonNull;
import androidx.exifinterface.media.ExifInterface;

import android.net.Uri;
import android.provider.MediaStore;

import java.util.ArrayList;
import java.util.Calendar;

import cn.ijero.pictureselector.data.LocalMedia;

public class PictureSelectorLoader {

    private PictureSelectorLoader() {
    }

    protected static final Uri QUERY_URI = MediaStore.Files.getContentUri("external");
    protected static final String[] PROJECTION = {
            MediaStore.Files.FileColumns._ID,
            MediaStore.MediaColumns.DATA,
            MediaStore.MediaColumns.MIME_TYPE,
            MediaStore.MediaColumns.WIDTH,
            MediaStore.MediaColumns.HEIGHT,
            "duration",
            MediaStore.MediaColumns.SIZE,
            "bucket_display_name",
            MediaStore.MediaColumns.DISPLAY_NAME,
            "bucket_id",
            "orientation",
            MediaStore.MediaColumns.DATE_ADDED,
    };
    protected static final String ORDER_BY = MediaStore.MediaColumns.DATE_MODIFIED + " DESC";

    public static ArrayList<LocalMedia> load(Context context) {
        ArrayList<LocalMedia> localMedias = new ArrayList<>();
        String selection = MediaStore.Files.FileColumns.MEDIA_TYPE + "=? OR " + MediaStore.Files.FileColumns.MEDIA_TYPE + "=? ";
        String[] selectionArgs = {String.valueOf(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE), String.valueOf(MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO),};
        Cursor cursor = context.getContentResolver().query(QUERY_URI, PROJECTION, selection, selectionArgs, ORDER_BY);
        try {
            if (cursor != null) {
                while (cursor.moveToNext()) {
                    int idIndex = cursor.getColumnIndexOrThrow(PROJECTION[0]);
                    int dataIndex = cursor.getColumnIndexOrThrow(PROJECTION[1]);
                    int mimeTypeIndex = cursor.getColumnIndexOrThrow(PROJECTION[2]);
                    int widthIndex = cursor.getColumnIndexOrThrow(PROJECTION[3]);
                    int heightIndex = cursor.getColumnIndexOrThrow(PROJECTION[4]);
                    int durationIndex = cursor.getColumnIndexOrThrow(PROJECTION[5]);
                    int sizeIndex = cursor.getColumnIndexOrThrow(PROJECTION[6]);
                    int bucketDisplayNameIndex = cursor.getColumnIndexOrThrow(PROJECTION[7]);
                    int displayNameIndex = cursor.getColumnIndexOrThrow(PROJECTION[8]);
                    int bucketIdIndex = cursor.getColumnIndexOrThrow(PROJECTION[9]);
                    int orientationIndex = cursor.getColumnIndexOrThrow(PROJECTION[10]);
                    int dateAddedIndex = cursor.getColumnIndexOrThrow(PROJECTION[11]);

                    int id = cursor.getInt(idIndex);
                    String data = cursor.getString(dataIndex);
                    String mimeType = cursor.getString(mimeTypeIndex);
                    int width = cursor.getInt(widthIndex);
                    int height = cursor.getInt(heightIndex);
                    long duration = cursor.getLong(durationIndex);
                    long size = cursor.getLong(sizeIndex);
                    String bucketDisplayName = cursor.getString(bucketDisplayNameIndex);
                    String displayName = cursor.getString(displayNameIndex);
                    long bucketId = cursor.getLong(bucketIdIndex);
                    int orientation = cursor.getInt(orientationIndex);
                    long dateAdded = cursor.getLong(dateAddedIndex) * 1000;

                    LocalMedia localMedia = new LocalMedia(id, data, mimeType, width, height, duration, size, bucketDisplayName, displayName, bucketId, orientation);
                    ExifInterface exifInterface = new ExifInterface(data);
                    localMedia.setLongitude(exifInterface.getAttribute(ExifInterface.TAG_GPS_LONGITUDE));
                    localMedia.setLatitude(exifInterface.getAttribute(ExifInterface.TAG_GPS_LATITUDE));
                    String datetime = getDatetime(dateAdded);
                    localMedia.setDatetime(datetime);
                    localMedias.add(localMedia);
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            if (cursor != null && !cursor.isClosed()) {
                cursor.close();
            }
        }

        return localMedias;
    }

    @NonNull
    private static String getDatetime(long dateAdded) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(dateAdded);
        @SuppressLint("DefaultLocale")
        String datetime = String.format("%04d/%02d/%02d %02d:%02d:%02d",
                calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH) + 1,
                calendar.get(Calendar.DAY_OF_MONTH),
                calendar.get(Calendar.HOUR_OF_DAY),
                calendar.get(Calendar.MINUTE),
                calendar.get(Calendar.SECOND));
        return datetime;
    }
}
